package org.truenewx.tnxjee.model.spec.user.security;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.util.Assert;
import org.truenewx.tnxjee.core.Strings;
import org.truenewx.tnxjee.core.util.StringUtil;

/**
 * 要求用户必须具备的权限
 */
public final class UserConfigAuthority implements ConfigAttribute {

    private static final long serialVersionUID = 912979753766969750L;

    public static final String SEPARATOR = Strings.PLUS;

    public static final String ATTRIBUTE_DENY_ALL = "denyAll";

    private String type;
    private String rank;
    private String permission;
    /**
     * 是否仅限内网访问
     */
    private boolean intranet;
    /**
     * 是否拒绝所有访问
     */
    private boolean denyAll;

    public UserConfigAuthority(String type, String rank, String permission, boolean intranet) {
        if (type == null) {
            type = Strings.EMPTY;
        }
        Assert.isTrue(!type.contains(SEPARATOR), () -> "The type can not contain '" + SEPARATOR + "'");
        if (rank == null) {
            rank = Strings.EMPTY;
        }
        Assert.isTrue(!rank.contains(SEPARATOR), () -> "The rank can not contain '" + SEPARATOR + "'");
        if (permission == null) {
            permission = Strings.EMPTY;
        }
        Assert.isTrue(!permission.contains(SEPARATOR), () -> "The permission can not contain '" + SEPARATOR + "'");
        this.type = type;
        this.rank = rank;
        this.permission = permission;
        this.intranet = intranet;
    }

    /**
     * 构建没有权限限制、登录即可访问的必备权限
     */
    public UserConfigAuthority() {
        this(null, null, null, false);
    }

    /**
     * 构建拒绝所有访问的必备权限
     *
     * @return 拒绝所有访问的必备权限
     */
    public static UserConfigAuthority ofDenyAll() {
        UserConfigAuthority authority = new UserConfigAuthority();
        authority.denyAll = true;
        return authority;
    }

    public String getType() {
        return this.type;
    }

    public String getRank() {
        return this.rank;
    }

    public String getPermission() {
        return this.permission;
    }

    public boolean isIntranet() {
        return this.intranet;
    }

    public boolean isDenyAll() {
        return this.denyAll;
    }

    @Override
    public String getAttribute() {
        return this.denyAll ? ATTRIBUTE_DENY_ALL : (this.type + SEPARATOR + this.rank + SEPARATOR + this.permission);
    }

    /**
     * 用指定来源配置权限覆盖当前配置权限，返回新的配置权限。覆盖规则：来源值不为空时覆盖当前值，否则保留当前值
     *
     * @param source 来源配置权限
     * @return 新的配置权限
     */
    public UserConfigAuthority override(UserConfigAuthority source) {
        if (source != null) {
            String type = StringUtil.ifBlank(source.type, this.type);
            String rank = StringUtil.ifBlank(source.rank, this.rank);
            String permission = StringUtil.ifBlank(source.permission, this.permission);
            return new UserConfigAuthority(type, rank, permission, source.intranet);
        }
        return this;
    }

    @Override
    public String toString() {
        return getAttribute();
    }

    @Override
    public UserConfigAuthority clone() {
        if (isDenyAll()) {
            return ofDenyAll();
        } else {
            return new UserConfigAuthority(getType(), getRank(), getPermission(), isIntranet());
        }
    }

}
